package com.test.springboot.springboot3securitydemo1.config;

import com.test.springboot.springboot3securitydemo1.auth.KaptchaAuthenticationProvider;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

/**
 * Created with IntelliJ IDEA.
 *
 * @author: liuziyang
 * @date: 2024/9/20-12:15
 * @description:
 * @modifiedBy:
 * @version: 1.0
 */
@EnableWebSecurity
@Configuration
public class SecurityConfig {

  @Primary
  @Bean
  public InMemoryUserDetailsManager userDetailsManager1() {
    return new InMemoryUserDetailsManager(
        User.builder().username("user1").password("{noop}123").roles("USER").build());
  }

  @Bean
  public InMemoryUserDetailsManager userDetailsManager2() {
    return new InMemoryUserDetailsManager(
        User.builder().username("user2").password("{noop}123").roles("USER").build());
  }

  /*@Bean
  public PasswordEncoder passwordEncoder(){
      return NoOpPasswordEncoder.getInstance();
  }*/

  @Bean
  public AuthenticationManager authenticationManager() {
    var provider1 = new KaptchaAuthenticationProvider();
    provider1.setUserDetailsService(userDetailsManager1());
    //    provider1.setPasswordEncoder(passwordEncoder());
    var provider2 = new KaptchaAuthenticationProvider();
    provider2.setUserDetailsService(userDetailsManager2());
    //    provider2.setPasswordEncoder(passwordEncoder());
    return new ProviderManager(List.of(provider1, provider2));
  }

  /*@Bean
  public WebSecurityCustomizer webSecurityCustomizer() {
    return webSecurity -> webSecurity.ignoring().requestMatchers("/vc.jpg");
  }*/

  @Bean
  public SecurityFilterChain securityFilterChain(
      HttpSecurity http, HttpServletResponse httpServletResponse) throws Exception {
    http.authorizeHttpRequests(
            authorize ->
                authorize.requestMatchers("/vc.jpg").permitAll().anyRequest().authenticated())
        .formLogin(
            customizer ->
                customizer
                    .loginPage("/login.html")
                    .loginProcessingUrl("/doLogin")
                    /* defaultSuccessUrl是通过重定向实现跳转（客户端跳转），而successForwardUrl则是通过服务器端跳转 */
                    .defaultSuccessUrl("/home.html")
                    .failureForwardUrl("/login.html")
                    .usernameParameter("uname")
                    .passwordParameter("passwd")
                    /*.successHandler(
                    (request, response, auth) -> {
                      var authorities = auth.getAuthorities();
                      System.out.println(Arrays.toString(authorities.toArray()));
                      response.setContentType("application/json;charset=utf-8");
                      Map<String, Object> resp = new HashMap<>();
                      resp.put("status", 200);
                      resp.put("msg", "success");
                      ObjectMapper mapper = new ObjectMapper();
                      final String json = mapper.writeValueAsString(resp);
                      response.getWriter().write(json);
                    })*/
                    .permitAll())
        .authenticationManager(authenticationManager())
        .httpBasic(AbstractHttpConfigurer::disable)
        .csrf(AbstractHttpConfigurer::disable);
    return http.build();
  }

  @Bean
  public InitializingBean initializingBean() {
    return () ->
        SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
  }
}
